package com.guli.mall.service.impl;
/*
 * @Author 罗
 * @date 2020/10/9 - 6:56 下午
 */

import com.alibaba.fastjson.JSON;
import com.guli.common.pojo.vo.StatusCodeEnum;
import com.guli.common.to.SpuEsTo;
import com.guli.common.utils.R;
import com.guli.mall.service.ProductService;
import com.guli.mall.serviceBase.globalException.MallException;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.DocWriteResponse;
import org.elasticsearch.action.bulk.BulkItemResponse;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.springframework.boot.autoconfigure.elasticsearch.rest.RestClientAutoConfiguration;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class ProductServiceImpl implements ProductService {

    @Resource
    RestHighLevelClient restHighLevelClient;

    @Override
    public R saveToProduct(List<SpuEsTo> spuEsToList) throws IOException {
        /**
            先要在建立索引的映射关系


         PUT product
         {
         "mappings": {
         "properties": {
         "skuId":{
         "type": "long"
         },
         "spuId":{
         "type": "keyword"
         },
         "skuTitle":{
         "type": "text",
         "analyzer": "ik_smart"
         },
         "skuPrice":{
         "type": "keyword"
         },
         "skuImg":{
         "type": "text",
         "index": false,
         "doc_values": false
         },
         "saleCount":{
         "type": "long"
         },
         "hasStock":{
         "type": "boolean"
         },
         "hotScore":{
         "type": "long"
         },
         "brandId": {
         "type": "long"
         },
         "brandName": {
         "type": "keyword",
         "index": false,
         "doc_values": false
         },
         "brandImg": {
         "type": "text",
         "index": false,
         "doc_values": false
         },
         "catelogId": {
         "type": "long"
         },
         "catelogName": {
         "type": "text",
         "index":false,
         "doc_values": false
         },
         "attrs":{
         "type": "nested",
         "properties": {
         "attrId":{
         "type":"long"
         },
         "attrName":{
         "type":"keyword",
         "index":false,
         "doc_values":false
         },
         "attrValue":{
         "type":"keyword"
         }
         }
         }
         }
         }
         }
         * */
        BulkRequest bulkRequest = new BulkRequest();


        spuEsToList.forEach(spuEsTo -> {
            IndexRequest request = new IndexRequest("product");

            request.source(JSON.toJSONString(spuEsTo), XContentType.JSON)
                    .id(String.valueOf(spuEsTo.getSkuId()));


//            restHighLevelClient.indexAsync(request, RequestOptions.DEFAULT, actionListener);

            bulkRequest.add(request);
        });

        BulkResponse bulkResponse = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);

        for (BulkItemResponse bulkItemResponse : bulkResponse) {

            DocWriteResponse itemResponse = bulkItemResponse.getResponse();

            switch (bulkItemResponse.getOpType()) {
                case INDEX:
                case CREATE:
                    IndexResponse indexResponse = (IndexResponse) itemResponse;
                    System.out.println("插入成功，响应是：" + indexResponse);
                    break;
                case UPDATE:
                    UpdateResponse updateResponse = (UpdateResponse) itemResponse;
                    System.out.println("更新成功，响应是：" + updateResponse);
                    break;
                case DELETE:
                    DeleteResponse deleteResponse = (DeleteResponse) itemResponse;
                    System.out.println("删除成功，响应是：" + deleteResponse);
            }
        }

        // 查看是否有哪一失败了
        if (bulkResponse.hasFailures()) {
            //TODO 处理单一 sku 保存失败的业务逻辑

            Map<String, String> errorItem = new HashMap<>();

            for (BulkItemResponse bulkItemResponse : bulkResponse) {

                if (bulkItemResponse.isFailed()) {
                    BulkItemResponse.Failure failure = bulkItemResponse.getFailure();
                    String errSkuId = bulkItemResponse.getId();
//                    throw new MallException("当前 skuId = "+errSkuId+"\t保存失败，"+failure.toString());

                    errorItem.put(errSkuId,failure.toString());

                    //throw new MallException(StatusCodeEnum.ELASTIC_SEARCH_UP_EXCEPTION.getCode(),"当前 skuId = "+errSkuId+"\t保存失败，"+failure.toString());
                }
            }

            return R.error().setData(errorItem);
        }

        return R.ok();

    }
}
